package com.lyn.tool.mvp.other;

import android.os.Handler;
import android.os.Message;
import android.util.Log;

import androidx.annotation.NonNull;

import java.lang.ref.WeakReference;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author Lyn
 * @date 2022/5/21
 * @desc
 */
public abstract class AsyncTask<R, P> {

    private final MyHandler<R, P> handler;

    public AsyncTask() {
        Log.e("lyn", "当前线程名字:" + Thread.currentThread().getName());
        handler = new MyHandler<R,P>(this);
    }

    protected void onPreExecute() {

    }

    protected abstract R doInBackground();

    protected void onProgressUpdate(P p) {

    }

    protected void onPostExecute(R R) {

    }

    public void setProgress(P p) {
        handler.removeMessages(ON_PROGRESS_UPDATE);
        handler.obtainMessage(ON_PROGRESS_UPDATE, p).sendToTarget();
    }

    public void execute(ThreadPoolExecutor poolExecutor) {
        onPreExecute();
        poolExecutor.execute(() -> {
            R r = doInBackground();
            handler.removeMessages(ON_POST_EXECUTE);
            handler.obtainMessage(ON_POST_EXECUTE, r).sendToTarget();
        });
    }


    private final static int ON_PROGRESS_UPDATE = 1;
    private final static int ON_POST_EXECUTE = 2;

    static class MyHandler<R, P> extends Handler {

        private WeakReference<AsyncTask<R, P>> myAsyncTaskWeakReference;

        public MyHandler(AsyncTask<R, P> asyncTask) {
            this.myAsyncTaskWeakReference = new WeakReference<>(asyncTask);
        }

        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            if (myAsyncTaskWeakReference != null) {
                switch (msg.what) {
                    case ON_POST_EXECUTE:
                        myAsyncTaskWeakReference.get().onPostExecute((R) msg.obj);
                        break;
                    case ON_PROGRESS_UPDATE:
                        myAsyncTaskWeakReference.get().onProgressUpdate((P) msg.obj);
                        break;
                }
            }
        }
    }
}
